Lab 11 Images - Exercises

These are some imports. You can skip this part.

In [10]:
%matplotlib inline
import math
from IPython.display import display, HTML
from skimage import data, io, filters, exposure
from skimage import util
from skimage.color import rgb2hsv, hsv2rgb, rgb2gray
from skimage.filters import gabor_kernel
from skimage.measure import moments, moments_central, moments_normalized, moments_hu
import numpy as np
from skimage.transform import resize
from scipy.stats import kurtosis
from scipy.stats import skew
from scipy.signal import fftconvolve
from scipy.ndimage import center_of_mass
from scipy import spatial
from pylab import *
import random

The LabImage class is used in this notebook to keep a data of an image. It contains the following fields:
a) img : an image object (numpy array),
b) ID : name of a file,
c) featuresValues: a feature vector. Each value of the feature vector corresponds to one predefined feature (characteristic/property of the image).

In [11]:
class LabImage:
    def __init__(self, img, ID):
        self.img = img
        self.ID = str(ID)
        self.featuresValues = []

The class Exercise maintains all data and provides methods for: loading images, displaying images end their characteristics, and searching for the most similar images of the collection to the provided query (image). You do not need to read the code. During the following exercises, you will be asked to implement (override) only two methods: functionOfSImilarity (it computes a similarity between two provided feature vectors) and featuresExtractor (it constructs a feature vector).

In [12]:
class Exercise:
    def __init__(self, folderPath, featuresNames = None, featuresExtractor = None):
        self.images = []
        self.featuresNames = []
        self.featuresExtractor = featuresExtractor
        self.loadAndCompute(folderPath, featuresNames, featuresExtractor)
        self.folderPath = folderPath
        
    def loadAndCompute(self, folderPath, featuresNames = None, featuresExtractor = None):
        collection = io.imread_collection(folderPath + "*.jpg")
        self.images = [LabImage(collection[i], collection.files[i]) for i in range(0, len(collection))]
        if featuresNames is not None:
            self.featuresNames = featuresNames
        if featuresExtractor is not None:
            for image in self.images:
                image.featuresValues = featuresExtractor(image.img)
                
    def searchForImage(self, folderPath, fileName, functionOfSImilarity, scale = 1.0,):
        queryImage = LabImage(io.imread(folderPath + fileName), fileName)
        queryImage.featuresValues = self.featuresExtractor(queryImage.img)
        orderedIDs = [i for i in range(0, len(self.images))]
        similarities = [functionOfSImilarity(queryImage.featuresValues, image.featuresValues) 
                        for image in self.images]
        
        tmp = list(zip(orderedIDs, similarities))
        tmp.sort(key = lambda x: x[1], reverse = True)
        orderedIDs, similarities = zip(*tmp)
        ### DISPLAY QUERY
        figure(figsize=(5.0 * scale, 5.0 * scale), dpi=80)
        subplot(1, 1, 1); plt.imshow(queryImage.img)
        plt.show()
        print(queryImage.ID)
        #features 
        data = []
        for j in range(0, len(self.featuresNames)):
            if isinstance(queryImage.featuresValues, np.ndarray): 
                fV = []
                fV.append("- "+ self.featuresNames[j])
                fV.append("NaN")
                data.append(fV)
            else:
                fV = []
                fV.append("- "+ self.featuresNames[j])
                fV.append("{:10.2f}".format(queryImage.featuresValues[j]))
                data.append(fV)
        
        col_width = max(len(word) for row in data for word in row) + 5 # PADDING
        for row in data:
            print("".join(word.ljust(col_width) for word in row))
        ### DISPLAY RESULTS
        self.display(scale = scale, orderedIDs = orderedIDs, similarities = similarities)
    
    def printStats(self, lIMG, rIMG, orderedIDs = [], similarities = []):
        data = []
        # names
        names = []
        for i in range(lIMG, rIMG):
            names.append(self.images[orderedIDs[i]].ID[len(self.folderPath):])
            names.append(" ")
        data.append(names)
        # similarities
        if len(similarities) > 0:
            sim = []
            for i in range(lIMG, rIMG):
                sim.append("Similarity")
                sim.append("{:10.2f}".format(similarities[i]))
            data.append(sim)
        #features 
        for j in range(0, len(self.featuresNames)):
            if isinstance(self.images[orderedIDs[i]].featuresValues, np.ndarray):
                fV = []
                for i in range(lIMG, rIMG):
                    fV.append("- "+ self.featuresNames[j])
                    fV.append("NaN")
                data.append(fV)         
            else:
                fV = []
                for i in range(lIMG, rIMG):
                    fV.append("- "+ self.featuresNames[j])
                    fV.append("{:10.2f}".format(self.images[orderedIDs[i]].featuresValues[j]))
                data.append(fV)
        
        col_width = max(len(word) for row in data for word in row) + 5 # PADDING
        for row in data:
            print("".join(word.ljust(col_width) for word in row))
            
    def display(self, scale = 1.0, orderedIDs = [], similarities = []):
        div = 3
        h = (len(self.images))/div
        if len(orderedIDs) == 0:
            orderedIDs = [i for i in range(0, len(self.images))]
        for i in range(0, math.ceil(h)):
            figure(figsize=(14.0 * scale, 5.0 * scale), dpi=80)
            idx = i * div
            for j in range(0, div):
                if (idx + j < len(self.images)):
                    subplot(2, div, j + 1); plt.imshow(self.images[orderedIDs[idx + j]].img)
            plt.show()
            end = min([len(self.images), i * div + div])
            self.printStats(i * div, end, orderedIDs = orderedIDs, similarities = similarities)

Exercise 1: Color Moments + Similarity

1.1) Color moments are measures which inform about a distribution of values of a particular color (e.g., blue) in an image. In the following, you are asked to implement the first three color moments (but, obviously, there are more). The first color moment is a mean value of a color.

Read the below code. Firstly, names of the features are defined (featuresNames_MeanColors). In this exercise you are asked to compute mean values of Red, Green, and Blue (RGB) colors (channels) of the images contained in "exercise1/intro" folder. For this purpose, complete the featuresExtractor_MeanColors method (as you may notice, featuresExtractor_MeanColors and featuresNames_MeanColors objects are passed to the constructor of the Exercise object) so that the method returns a 3-element feature vector which contains mean values of each color (red, green, blue; use np.mean()). Then, run the script and analyse the results:

i) What is the difference between the feature vector of the image 1.jpg and the feature vector of the image 2.jpg?
ii) Why are all the feature vectors of the images 3.jpg-6.jpg the same?
iii) Considering images 7.jpg-9.jpg, why is the mean of the red color the smallest for 9.jpg and is the greatest for 8.jpg?

In [13]:
featuresNames_MeanColors = ["red mean", "green mean", "blue mean"]

# TODO 
def featuresExtractor_MeanColors(image):
    values = [np.mean(image[:,:,0]),np.mean(image[:,:,1]),np.mean(image[:,:,2])]
    return values
    
e1 = Exercise("exercise1/intro/", featuresNames_MeanColors, featuresExtractor_MeanColors)
e1.display(scale = 1.0)

#1 1.jpg is pure red and 2.jpg is pure blue.
#2 Color shapes are different but they cocver equal percentage of an image.
#3 Becouse of brightness of an image. The darker it is, the less color value it has.
1.jpg                             2.jpg                             3.jpg                             
- red mean           255.00       - red mean             0.00       - red mean           127.50       
- green mean           0.00       - green mean           0.00       - green mean           0.00       
- blue mean            0.00       - blue mean          255.00       - blue mean          127.50       
4.jpg                             5.jpg                             6.jpg                             
- red mean           127.50       - red mean           127.50       - red mean           127.50       
- green mean           0.00       - green mean           0.00       - green mean           0.00       
- blue mean          127.50       - blue mean          127.50       - blue mean          127.50       
7.jpg                             8.jpg                             9.jpg                             
- red mean           128.00       - red mean           146.12       - red mean           112.66       
- green mean           0.00       - green mean           0.09       - green mean           0.09       
- blue mean            0.00       - blue mean            0.05       - blue mean            0.11       

1.2) The second color moment is a standard deviation. Complete the feturesExtractor_StdColors method so that it computes and returns a 3-element feature vector which containts the standard deviation of the red, green, and blue color (use np.std()). Run the script and analyse the results:

i) Why are all the feature vectors of the images 1.jpg-2.jpg the same (and equal to zero)?
ii) Why are all the feature vectors of the images 3.jpg-6.jpg the same?

In [15]:
featuresNames_StdColors = ["red std", "green std", "blue std"]

# TODO
def featuresExtractor_StdColors(image):
    values = [np.std(image[:,:,0]),np.std(image[:,:,1]),np.std(image[:,:,2])]
    return values
    
e1 = Exercise("exercise1/intro/", featuresNames_StdColors, featuresExtractor_StdColors)
e1.display(scale = 1.0)

#1 Becouse they are pure red and blue colors
#2 Color shapes are different but they cocver equal percentage of an image.
1.jpg                           2.jpg                           3.jpg                           
- red std             0.00      - red std             0.00      - red std           127.50      
- green std           0.00      - green std           0.00      - green std           0.00      
- blue std            0.00      - blue std            0.00      - blue std          127.50      
4.jpg                           5.jpg                           6.jpg                           
- red std           127.50      - red std           127.50      - red std           127.50      
- green std           0.00      - green std           0.00      - green std           0.00      
- blue std          127.50      - blue std          127.50      - blue std          127.50      
7.jpg                           8.jpg                           9.jpg                           
- red std             0.00      - red std            32.80      - red std            24.02      
- green std           0.00      - green std           0.29      - green std           0.29      
- blue std            0.00      - blue std            0.23      - blue std            0.32      

1.3) The third color moment is a skeweness. The skeweness measures how asymmetric is the distribution (positive value = the right tail of the distribution is longer; negative value = the left tail of the distribution is longer). Complete the feturesExtractor_SkewColors method so that it computes and returns a 3-element feature vector containing skeweness of the red, green, and blue color (use skew() + you must transform numpy array to 1-D array; use .ravel() ). Run the script and analyse the results:
i) Why are all the feature vectors of images 1.jpg-6.jpg the same (and all the values equal to zero)?
ii) Why is the skeweness of the distribution of the red color in image 8.jpg positive but in image 9.jpg is negative?

In [16]:
featuresNames_SkewColors = ["red skew", "green skew", "blue skew"]

# TODO
def featuresExtractor_SkewColors(image):
    values = [skew(image[:,:,0].ravel()), skew(image[:,:,1].ravel()), skew(image[:,:,2].ravel())]
    return values
    
e1 = Exercise("exercise1/intro/", featuresNames_SkewColors, featuresExtractor_SkewColors)
e1.display(scale = 1.0)

#1 Because images 1.jpg-6.jpg are all symmetric
#2 Because image 8.jpg is brighter on the right sight in contrast to 9.jpg.
1.jpg                             2.jpg                             3.jpg                             
- red skew             0.00       - red skew             0.00       - red skew             0.00       
- green skew           0.00       - green skew           0.00       - green skew           0.00       
- blue skew            0.00       - blue skew            0.00       - blue skew            0.00       
4.jpg                             5.jpg                             6.jpg                             
- red skew             0.00       - red skew             0.00       - red skew             0.00       
- green skew           0.00       - green skew           0.00       - green skew           0.00       
- blue skew            0.00       - blue skew            0.00       - blue skew            0.00       
7.jpg                             8.jpg                             9.jpg                             
- red skew             0.00       - red skew             2.06       - red skew            -1.57       
- green skew           0.00       - green skew           3.13       - green skew           2.98       
- blue skew            0.00       - blue skew            4.02       - blue skew            2.62       

1.4) Run the below script. This example involves real pictures. Analyse the computed feature vectors (returned by featuresExtractor_MeanColor method). Can you justify the results?
i) Consider the image b1_blue.jpg. Which color has the greatest mean value and which has the lowest? Compare it with the image b3_blue.jpg. Which color is the most dominant one now? Can you justify the difference between these feature vectors by comparing the pictures?
ii) Why are the mean values of the feature vector of the image b6_dark.jpg very low, while they are very high for the b16_white.jpg?
iii) Which of these pictures is "the most red" in your opinion? Look only at the pictures. Then, check the mean value of the red color of the chosen picture. Is it the greatest among all pictures?

In [17]:
e1 = Exercise("exercise1/base/", featuresNames_MeanColors, featuresExtractor_MeanColors)
e1.display(scale = 1.0)

#1 It is possible to justify the difference comparing both pictures.
#2 Because the darker color is, the lowest color values it has
#3 b13_red.jpg is the most red in my opinion. It hasn't got the greatest red value becouse of the darknes in the image.
b1_blue.jpg                       b2_blue.jpg                       b3_blue.jpg                       
- red mean            91.31       - red mean            49.20       - red mean            75.93       
- green mean         140.78       - green mean         101.92       - green mean         104.11       
- blue mean          158.17       - blue mean          114.21       - blue mean           86.29       
b4_blue.jpg                       b5_blue.jpg                       b6_dark.jpg                       
- red mean            72.91       - red mean           106.24       - red mean            45.42       
- green mean         128.36       - green mean         151.43       - green mean          38.85       
- blue mean          163.16       - blue mean          161.61       - blue mean           57.53       
b7_night.jpg                      b8_night.jpg                      b9_night.jpg                      
- red mean            47.57       - red mean            66.40       - red mean            66.73       
- green mean          44.92       - green mean          66.53       - green mean          42.90       
- blue mean           51.92       - blue mean           72.24       - blue mean           37.88       
b10_night.jpg                       b11_red.jpg                         b12_red.jpg                         
- red mean             29.84        - red mean            109.33        - red mean            121.55        
- green mean           33.08        - green mean           63.50        - green mean           69.92        
- blue mean            55.93        - blue mean            45.15        - blue mean            12.09        
b13_red.jpg                       b14_red.jpg                       b15_red.jpg                       
- red mean            86.68       - red mean           138.84       - red mean           164.96       
- green mean          28.51       - green mean          79.14       - green mean          75.42       
- blue mean           24.68       - blue mean           76.32       - blue mean           17.71       
b16_white.jpg                       b17_white.jpg                       b18_white.jpg                       
- red mean            198.59        - red mean            106.59        - red mean            177.67        
- green mean          210.60        - green mean          124.14        - green mean          184.47        
- blue mean           238.11        - blue mean           162.22        - blue mean           197.93        
b19_white.jpg                       b20_white.jpg                       b21_green.jpg                       
- red mean             90.33        - red mean            171.43        - red mean            104.58        
- green mean          109.64        - green mean          181.98        - green mean          150.14        
- blue mean           130.01        - blue mean           192.86        - blue mean            39.53        
b22_green.jpg                       b23_green.jpg                       b24_green.jpg                       
- red mean             89.23        - red mean             73.10        - red mean            131.89        
- green mean           65.61        - green mean          101.08        - green mean          164.07        
- blue mean            29.22        - blue mean            50.68        - blue mean           157.94        
b25_green.jpg                       
- red mean            125.24        
- green mean          153.94        
- blue mean            31.49        

1.5) Now, it is time to build a simple seach engine for finding images. Your task is to complete the cosineSimilarity method which measures similarity between the two provided feature vectors. The greater is the returned value, the greater is the similarity. As the name of the method suggests, use a cosine similarity which is the cosine of the angle between the two vectors. You can use the spatial.distance.cosine() method. However, it returns a distance (the smaller value the better), not a similarity (the greater value the better). You have to handle this issue. Then, run the script.

Firstly, the method searchForImage loads and displays the selected query image (q1_red.jpg), and derives its feature vector (featuresExtractor_MeanColor is used to extract feature vectors). Then, images from "exercise1/base" folder are displayed in the order of similarity to the query image. Do you agree with the ranking? Why? Why not? Why is b9_night.jpg ranked better than b15_red.jpg?

In [18]:
def cosineSimilarity(featuresQuery, featuresImage):
    distance = spatial.distance.cosine(featuresQuery, featuresImage)
    return 1/distance

e1 = Exercise("exercise1/base/", featuresNames_MeanColors, featuresExtractor_MeanColors)
e1.searchForImage("exercise1/query/", "q1_red.jpg", cosineSimilarity)

#1 I don't agree with the rating. It compares images only through colors.
#2 b9_night.jpg is ranked better than b15_red.jpg because it has closer relationship between colors compared to searching image.
q1_red.jpg
- red mean           137.36       
- green mean          74.62       
- blue mean           48.14       
b11_red.jpg                         b22_green.jpg                       b14_red.jpg                         
Similarity            742.84        Similarity            106.20        Similarity             91.46        
- red mean            109.33        - red mean             89.23        - red mean            138.84        
- green mean           63.50        - green mean           65.61        - green mean           79.14        
- blue mean            45.15        - blue mean            29.22        - blue mean            76.32        
b9_night.jpg                      b13_red.jpg                       b15_red.jpg                       
Similarity            76.35       Similarity            64.60       Similarity            44.51       
- red mean            66.73       - red mean            86.68       - red mean           164.96       
- green mean          42.90       - green mean          28.51       - green mean          75.42       
- blue mean           37.88       - blue mean           24.68       - blue mean           17.71       
b12_red.jpg                         b25_green.jpg                       b23_green.jpg                       
Similarity             43.81        Similarity             12.36        Similarity             11.01        
- red mean            121.55        - red mean            125.24        - red mean             73.10        
- green mean           69.92        - green mean          153.94        - green mean          101.08        
- blue mean            12.09        - blue mean            31.49        - blue mean            50.68        
b7_night.jpg                        b8_night.jpg                        b18_white.jpg                       
Similarity             10.70        Similarity             10.61        Similarity             10.09        
- red mean             47.57        - red mean             66.40        - red mean            177.67        
- green mean           44.92        - green mean           66.53        - green mean          184.47        
- blue mean            51.92        - blue mean            72.24        - blue mean           197.93        
b20_white.jpg                       b21_green.jpg                       b16_white.jpg                       
Similarity              9.87        Similarity              9.73        Similarity              8.95        
- red mean            171.43        - red mean            104.58        - red mean            198.59        
- green mean          181.98        - green mean          150.14        - green mean          210.60        
- blue mean           192.86        - blue mean            39.53        - blue mean           238.11        
b24_green.jpg                       b3_blue.jpg                         b6_dark.jpg                         
Similarity              8.47        Similarity              8.42        Similarity              8.17        
- red mean            131.89        - red mean             75.93        - red mean             45.42        
- green mean          164.07        - green mean          104.11        - green mean           38.85        
- blue mean           157.94        - blue mean            86.29        - blue mean            57.53        
b19_white.jpg                       b17_white.jpg                       b5_blue.jpg                         
Similarity              6.77        Similarity              6.31        Similarity              6.18        
- red mean             90.33        - red mean            106.59        - red mean            106.24        
- green mean          109.64        - green mean          124.14        - green mean          151.43        
- blue mean           130.01        - blue mean           162.22        - blue mean           161.61        
b1_blue.jpg                         b10_night.jpg                       b4_blue.jpg                         
Similarity              5.35        Similarity              4.80        Similarity              4.21        
- red mean             91.31        - red mean             29.84        - red mean             72.91        
- green mean          140.78        - green mean           33.08        - green mean          128.36        
- blue mean           158.17        - blue mean            55.93        - blue mean           163.16        
b2_blue.jpg                       
Similarity             4.08       
- red mean            49.20       
- green mean         101.92       
- blue mean          114.21       

1.6) Search for the most similar images to q2_green.jpg. Verify the results.

In [19]:
e1.searchForImage("exercise1/query/", "q2_green.jpg", cosineSimilarity)
q2_green.jpg
- red mean           127.21       
- green mean         142.08       
- blue mean           64.78       
b23_green.jpg                       b21_green.jpg                       b25_green.jpg                       
Similarity            154.79        Similarity             74.47        Similarity             64.63        
- red mean             73.10        - red mean            104.58        - red mean            125.24        
- green mean          101.08        - green mean          150.14        - green mean          153.94        
- blue mean            50.68        - blue mean            39.53        - blue mean            31.49        
b22_green.jpg                       b9_night.jpg                        b3_blue.jpg                         
Similarity             45.73        Similarity             26.51        Similarity             26.16        
- red mean             89.23        - red mean             66.73        - red mean             75.93        
- green mean           65.61        - green mean           42.90        - green mean          104.11        
- blue mean            29.22        - blue mean            37.88        - blue mean            86.29        
b11_red.jpg                         b24_green.jpg                       b14_red.jpg                         
Similarity             22.82        Similarity             19.74        Similarity             19.60        
- red mean            109.33        - red mean            131.89        - red mean            138.84        
- green mean           63.50        - green mean          164.07        - green mean           79.14        
- blue mean            45.15        - blue mean           157.94        - blue mean            76.32        
b20_white.jpg                       b8_night.jpg                        b18_white.jpg                       
Similarity             18.50        Similarity             18.40        Similarity             18.31        
- red mean            171.43        - red mean             66.40        - red mean            177.67        
- green mean          181.98        - green mean           66.53        - green mean          184.47        
- blue mean           192.86        - blue mean            72.24        - blue mean           197.93        
b7_night.jpg                        b16_white.jpg                       b12_red.jpg                         
Similarity             16.41        Similarity             15.46        Similarity             13.08        
- red mean             47.57        - red mean            198.59        - red mean            121.55        
- green mean           44.92        - green mean          210.60        - green mean           69.92        
- blue mean            51.92        - blue mean           238.11        - blue mean            12.09        
b5_blue.jpg                         b19_white.jpg                       b1_blue.jpg                         
Similarity             12.45        Similarity             11.77        Similarity             10.14        
- red mean            106.24        - red mean             90.33        - red mean             91.31        
- green mean          151.43        - green mean          109.64        - green mean          140.78        
- blue mean           161.61        - blue mean           130.01        - blue mean           158.17        
b6_dark.jpg                         b17_white.jpg                       b15_red.jpg                         
Similarity              9.92        Similarity              9.87        Similarity              9.51        
- red mean             45.42        - red mean            106.59        - red mean            164.96        
- green mean           38.85        - green mean          124.14        - green mean           75.42        
- blue mean            57.53        - blue mean           162.22        - blue mean            17.71        
b13_red.jpg                       b2_blue.jpg                       b4_blue.jpg                       
Similarity             8.06       Similarity             7.63       Similarity             7.11       
- red mean            86.68       - red mean            49.20       - red mean            72.91       
- green mean          28.51       - green mean         101.92       - green mean         128.36       
- blue mean           24.68       - blue mean          114.21       - blue mean          163.16       
b10_night.jpg                       
Similarity              6.31        
- red mean             29.84        
- green mean           33.08        
- blue mean            55.93        

1.7) Search for the most similar images to q3_blue.jpg. Verify the results.

In [20]:
e1.searchForImage("exercise1/query/", "q3_blue.jpg", cosineSimilarity)
q3_blue.jpg
- red mean            93.09       
- green mean         128.93       
- blue mean          143.78       
b5_blue.jpg                         b1_blue.jpg                         b19_white.jpg                       
Similarity           5087.40        Similarity           1124.93        Similarity            883.83        
- red mean            106.24        - red mean             91.31        - red mean             90.33        
- green mean          151.43        - green mean          140.78        - green mean          109.64        
- blue mean           161.61        - blue mean           158.17        - blue mean           130.01        
b17_white.jpg                       b24_green.jpg                       b16_white.jpg                       
Similarity            342.39        Similarity            201.17        Similarity            167.26        
- red mean            106.59        - red mean            131.89        - red mean            198.59        
- green mean          124.14        - green mean          164.07        - green mean          210.60        
- blue mean           162.22        - blue mean           157.94        - blue mean           238.11        
b4_blue.jpg                         b20_white.jpg                       b18_white.jpg                       
Similarity            125.57        Similarity            124.74        Similarity            113.34        
- red mean             72.91        - red mean            171.43        - red mean            177.67        
- green mean          128.36        - green mean          181.98        - green mean          184.47        
- blue mean           163.16        - blue mean           192.86        - blue mean           197.93        
b2_blue.jpg                       b3_blue.jpg                       b8_night.jpg                      
Similarity           104.85       Similarity            95.17       Similarity            94.25       
- red mean            49.20       - red mean            75.93       - red mean            66.40       
- green mean         101.92       - green mean         104.11       - green mean          66.53       
- blue mean          114.21       - blue mean           86.29       - blue mean           72.24       
b7_night.jpg                        b6_dark.jpg                         b10_night.jpg                       
Similarity             80.82        Similarity             64.33        Similarity             62.53        
- red mean             47.57        - red mean             45.42        - red mean             29.84        
- green mean           44.92        - green mean           38.85        - green mean           33.08        
- blue mean            51.92        - blue mean            57.53        - blue mean            55.93        
b23_green.jpg                       b9_night.jpg                        b14_red.jpg                         
Similarity             16.57        Similarity             11.37        Similarity              9.82        
- red mean             73.10        - red mean             66.73        - red mean            138.84        
- green mean          101.08        - green mean           42.90        - green mean           79.14        
- blue mean            50.68        - blue mean            37.88        - blue mean            76.32        
b21_green.jpg                       b11_red.jpg                         b22_green.jpg                       
Similarity              7.49        Similarity              7.33        Similarity              6.84        
- red mean            104.58        - red mean            109.33        - red mean             89.23        
- green mean          150.14        - green mean           63.50        - green mean           65.61        
- blue mean            39.53        - blue mean            45.15        - blue mean            29.22        
b25_green.jpg                       b13_red.jpg                         b12_red.jpg                         
Similarity              6.12        Similarity              4.08        Similarity              3.72        
- red mean            125.24        - red mean             86.68        - red mean            121.55        
- green mean          153.94        - green mean           28.51        - green mean           69.92        
- blue mean            31.49        - blue mean            24.68        - blue mean            12.09        
b15_red.jpg                       
Similarity             3.41       
- red mean           164.96       
- green mean          75.42       
- blue mean           17.71       

1.8) Search for the most similar images to q4_white.jpg. Verify the results.

In [21]:
e1.searchForImage("exercise1/query/", "q4_white.jpg", cosineSimilarity)
q4_white.jpg
- red mean           120.71       
- green mean         133.53       
- blue mean          157.62       
b16_white.jpg                       b19_white.jpg                       b20_white.jpg                       
Similarity           1656.42        Similarity           1211.16        Similarity            486.41        
- red mean            198.59        - red mean             90.33        - red mean            171.43        
- green mean          210.60        - green mean          109.64        - green mean          181.98        
- blue mean           238.11        - blue mean           130.01        - blue mean           192.86        
b17_white.jpg                       b18_white.jpg                       b8_night.jpg                        
Similarity            478.57        Similarity            460.29        Similarity            361.13        
- red mean            106.59        - red mean            177.67        - red mean             66.40        
- green mean          124.14        - green mean          184.47        - green mean           66.53        
- blue mean           162.22        - blue mean           197.93        - blue mean            72.24        
b7_night.jpg                        b24_green.jpg                       b5_blue.jpg                         
Similarity            332.64        Similarity            259.02        Similarity            232.62        
- red mean             47.57        - red mean            131.89        - red mean            106.24        
- green mean           44.92        - green mean          164.07        - green mean          151.43        
- blue mean            51.92        - blue mean           157.94        - blue mean           161.61        
b6_dark.jpg                       b1_blue.jpg                       b3_blue.jpg                       
Similarity           179.75       Similarity           130.98       Similarity            85.00       
- red mean            45.42       - red mean            91.31       - red mean            75.93       
- green mean          38.85       - green mean         140.78       - green mean         104.11       
- blue mean           57.53       - blue mean          158.17       - blue mean           86.29       
b10_night.jpg                       b4_blue.jpg                         b2_blue.jpg                         
Similarity             62.61        Similarity             53.36        Similarity             41.81        
- red mean             29.84        - red mean             72.91        - red mean             49.20        
- green mean           33.08        - green mean          128.36        - green mean          101.92        
- blue mean            55.93        - blue mean           163.16        - blue mean           114.21        
b23_green.jpg                       b9_night.jpg                        b14_red.jpg                         
Similarity             16.90        Similarity             16.45        Similarity             14.05        
- red mean             73.10        - red mean             66.73        - red mean            138.84        
- green mean          101.08        - green mean           42.90        - green mean           79.14        
- blue mean            50.68        - blue mean            37.88        - blue mean            76.32        
b11_red.jpg                         b22_green.jpg                       b21_green.jpg                       
Similarity              9.65        Similarity              8.38        Similarity              7.61        
- red mean            109.33        - red mean             89.23        - red mean            104.58        
- green mean           63.50        - green mean           65.61        - green mean          150.14        
- blue mean            45.15        - blue mean            29.22        - blue mean            39.53        
b25_green.jpg                       b13_red.jpg                         b12_red.jpg                         
Similarity              6.46        Similarity              5.08        Similarity              4.34        
- red mean            125.24        - red mean             86.68        - red mean            121.55        
- green mean          153.94        - green mean           28.51        - green mean           69.92        
- blue mean            31.49        - blue mean            24.68        - blue mean            12.09        
b15_red.jpg                       
Similarity             4.03       
- red mean           164.96       
- green mean          75.42       
- blue mean           17.71       

1.9) Search for the most similar images to q5_dark.jpg. Verify the results.

In [22]:
e1.searchForImage("exercise1/query/", "q5_dark.jpg", cosineSimilarity)
q5_dark.jpg
- red mean            24.89       
- green mean          25.89       
- blue mean           26.53       
b18_white.jpg                       b20_white.jpg                       b8_night.jpg                        
Similarity           4222.57        Similarity           4001.06        Similarity           3390.36        
- red mean            177.67        - red mean            171.43        - red mean             66.40        
- green mean          184.47        - green mean          181.98        - green mean           66.53        
- blue mean           197.93        - blue mean           192.86        - blue mean            72.24        
b7_night.jpg                        b16_white.jpg                       b24_green.jpg                       
Similarity            749.91        Similarity            719.93        Similarity            392.36        
- red mean             47.57        - red mean            198.59        - red mean            131.89        
- green mean           44.92        - green mean          210.60        - green mean          164.07        
- blue mean            51.92        - blue mean           238.11        - blue mean           157.94        
b3_blue.jpg                         b19_white.jpg                       b5_blue.jpg                         
Similarity            139.04        Similarity            138.14        Similarity             95.20        
- red mean             75.93        - red mean             90.33        - red mean            106.24        
- green mean          104.11        - green mean          109.64        - green mean          151.43        
- blue mean            86.29        - blue mean           130.01        - blue mean           161.61        
b6_dark.jpg                         b17_white.jpg                       b1_blue.jpg                         
Similarity             89.12        Similarity             87.87        Similarity             56.45        
- red mean             45.42        - red mean            106.59        - red mean             91.31        
- green mean           38.85        - green mean          124.14        - green mean          140.78        
- blue mean            57.53        - blue mean           162.22        - blue mean           158.17        
b10_night.jpg                       b4_blue.jpg                         b9_night.jpg                        
Similarity             29.10        Similarity             27.45        Similarity             26.41        
- red mean             29.84        - red mean             72.91        - red mean             66.73        
- green mean           33.08        - green mean          128.36        - green mean           42.90        
- blue mean            55.93        - blue mean           163.16        - blue mean            37.88        
b23_green.jpg                       b2_blue.jpg                         b14_red.jpg                         
Similarity             26.04        Similarity             25.11        Similarity             20.91        
- red mean             73.10        - red mean             49.20        - red mean            138.84        
- green mean          101.08        - green mean          101.92        - green mean           79.14        
- blue mean            50.68        - blue mean           114.21        - blue mean            76.32        
b11_red.jpg                         b22_green.jpg                       b21_green.jpg                       
Similarity             13.90        Similarity             12.19        Similarity             10.20        
- red mean            109.33        - red mean             89.23        - red mean            104.58        
- green mean           63.50        - green mean           65.61        - green mean          150.14        
- blue mean            45.15        - blue mean            29.22        - blue mean            39.53        
b25_green.jpg                       b13_red.jpg                         b12_red.jpg                         
Similarity              8.68        Similarity              6.30        Similarity              5.57        
- red mean            125.24        - red mean             86.68        - red mean            121.55        
- green mean          153.94        - green mean           28.51        - green mean           69.92        
- blue mean            31.49        - blue mean            24.68        - blue mean            12.09        
b15_red.jpg                       
Similarity             5.06       
- red mean           164.96       
- green mean          75.42       
- blue mean           17.71       

1.10) You should find the results for the query image = q5_dark.jpg not satisfactory. What is the reason?
Now, use another function of similarity. Use euclidean distance to compute similarity between the two feacture vectors. You can use spatial.distance.euclidean() method but remember that it returns a distance, not a similarity.

In [23]:
# because relationship between color values is more important than accual color values.

# TODO
def euclideanSimilarity(featuresQuery, featuresImage):
    distance = spatial.distance.euclidean(featuresQuery, featuresImage)
    return 1/distance

1.11) Search for the most similar images to q5_dark.jpg using euclideanSimilarity method. Do you find the results much better?

In [24]:
e1.searchForImage("exercise1/query/", "q5_dark.jpg", euclideanSimilarity)
q5_dark.jpg
- red mean            24.89       
- green mean          25.89       
- blue mean           26.53       
b10_night.jpg                       b7_night.jpg                        b6_dark.jpg                         
Similarity              0.03        Similarity              0.03        Similarity              0.03        
- red mean             29.84        - red mean             47.57        - red mean             45.42        
- green mean           33.08        - green mean           44.92        - green mean           38.85        
- blue mean            55.93        - blue mean            51.92        - blue mean            57.53        
b9_night.jpg                      b13_red.jpg                       b8_night.jpg                      
Similarity             0.02       Similarity             0.02       Similarity             0.01       
- red mean            66.73       - red mean            86.68       - red mean            66.40       
- green mean          42.90       - green mean          28.51       - green mean          66.53       
- blue mean           37.88       - blue mean           24.68       - blue mean           72.24       
b22_green.jpg                       b23_green.jpg                       b11_red.jpg                         
Similarity              0.01        Similarity              0.01        Similarity              0.01        
- red mean             89.23        - red mean             73.10        - red mean            109.33        
- green mean           65.61        - green mean          101.08        - green mean           63.50        
- blue mean            29.22        - blue mean            50.68        - blue mean            45.15        
b12_red.jpg                       b3_blue.jpg                       b2_blue.jpg                       
Similarity             0.01       Similarity             0.01       Similarity             0.01       
- red mean           121.55       - red mean            75.93       - red mean            49.20       
- green mean          69.92       - green mean         104.11       - green mean         101.92       
- blue mean           12.09       - blue mean           86.29       - blue mean          114.21       
b14_red.jpg                         b21_green.jpg                       b19_white.jpg                       
Similarity              0.01        Similarity              0.01        Similarity              0.01        
- red mean            138.84        - red mean            104.58        - red mean             90.33        
- green mean           79.14        - green mean          150.14        - green mean          109.64        
- blue mean            76.32        - blue mean            39.53        - blue mean           130.01        
b15_red.jpg                         b25_green.jpg                       b4_blue.jpg                         
Similarity              0.01        Similarity              0.01        Similarity              0.01        
- red mean            164.96        - red mean            125.24        - red mean             72.91        
- green mean           75.42        - green mean          153.94        - green mean          128.36        
- blue mean            17.71        - blue mean            31.49        - blue mean           163.16        
b17_white.jpg                       b1_blue.jpg                         b5_blue.jpg                         
Similarity              0.01        Similarity              0.01        Similarity              0.00        
- red mean            106.59        - red mean             91.31        - red mean            106.24        
- green mean          124.14        - green mean          140.78        - green mean          151.43        
- blue mean           162.22        - blue mean           158.17        - blue mean           161.61        
b24_green.jpg                       b20_white.jpg                       b18_white.jpg                       
Similarity              0.00        Similarity              0.00        Similarity              0.00        
- red mean            131.89        - red mean            171.43        - red mean            177.67        
- green mean          164.07        - green mean          181.98        - green mean          184.47        
- blue mean           157.94        - blue mean           192.86        - blue mean           197.93        
b16_white.jpg                       
Similarity              0.00        
- red mean            198.59        
- green mean          210.60        
- blue mean           238.11        

1.12) Do the same for query image "q4_white.jpg". Why are the results not satisfactory?

In [25]:
e1.searchForImage("exercise1/query/", "q4_white.jpg", euclideanSimilarity)
# euclidean distance is distance between two POINTS, which is reasonable when we compare dark pictures (where the mean values are small and we consider means as set of points, not as vector)
q4_white.jpg
- red mean           120.71       
- green mean         133.53       
- blue mean          157.62       
b17_white.jpg                       b5_blue.jpg                         b1_blue.jpg                         
Similarity              0.06        Similarity              0.04        Similarity              0.03        
- red mean            106.59        - red mean            106.24        - red mean             91.31        
- green mean          124.14        - green mean          151.43        - green mean          140.78        
- blue mean           162.22        - blue mean           161.61        - blue mean           158.17        
b24_green.jpg                       b19_white.jpg                       b4_blue.jpg                         
Similarity              0.03        Similarity              0.02        Similarity              0.02        
- red mean            131.89        - red mean             90.33        - red mean             72.91        
- green mean          164.07        - green mean          109.64        - green mean          128.36        
- blue mean           157.94        - blue mean           130.01        - blue mean           163.16        
b20_white.jpg                       b18_white.jpg                       b3_blue.jpg                         
Similarity              0.01        Similarity              0.01        Similarity              0.01        
- red mean            171.43        - red mean            177.67        - red mean             75.93        
- green mean          181.98        - green mean          184.47        - green mean          104.11        
- blue mean           192.86        - blue mean           197.93        - blue mean            86.29        
b2_blue.jpg                         b14_red.jpg                         b21_green.jpg                       
Similarity              0.01        Similarity              0.01        Similarity              0.01        
- red mean             49.20        - red mean            138.84        - red mean            104.58        
- green mean          101.92        - green mean           79.14        - green mean          150.14        
- blue mean           114.21        - blue mean            76.32        - blue mean            39.53        
b8_night.jpg                        b23_green.jpg                       b25_green.jpg                       
Similarity              0.01        Similarity              0.01        Similarity              0.01        
- red mean             66.40        - red mean             73.10        - red mean            125.24        
- green mean           66.53        - green mean          101.08        - green mean          153.94        
- blue mean            72.24        - blue mean            50.68        - blue mean            31.49        
b11_red.jpg                         b16_white.jpg                       b22_green.jpg                       
Similarity              0.01        Similarity              0.01        Similarity              0.01        
- red mean            109.33        - red mean            198.59        - red mean             89.23        
- green mean           63.50        - green mean          210.60        - green mean           65.61        
- blue mean            45.15        - blue mean           238.11        - blue mean            29.22        
b7_night.jpg                      b6_dark.jpg                       b15_red.jpg                       
Similarity             0.01       Similarity             0.01       Similarity             0.01       
- red mean            47.57       - red mean            45.42       - red mean           164.96       
- green mean          44.92       - green mean          38.85       - green mean          75.42       
- blue mean           51.92       - blue mean           57.53       - blue mean           17.71       
b12_red.jpg                         b9_night.jpg                        b10_night.jpg                       
Similarity              0.01        Similarity              0.01        Similarity              0.01        
- red mean            121.55        - red mean             66.73        - red mean             29.84        
- green mean           69.92        - green mean           42.90        - green mean           33.08        
- blue mean            12.09        - blue mean            37.88        - blue mean            55.93        
b13_red.jpg                       
Similarity             0.01       
- red mean            86.68       
- green mean          28.51       
- blue mean           24.68       

Exercise 2: Shapes + Centroid + Moment Invariants + Hu Moments

2.1) In Exercise 1 you have derived image properties based on its color. Apart from the color, one may analyse a shape of an object (objects) contained in the picture. The measures which account for this are called image moments. Via image moments one may derive, e.g, an area, a total intensity, or a centroid of an object. However, it is important to remember that a segmentation of the image must be performed first in order to extract objects from the image.

In this exercise you are asked to compute centroids of the red, green, and blue color components. Use center_of_mass() method. It returns a pair of values [row - y coordinate, column - x coordinate] for a given matrix. Run the script and analyse the results:
i) What is the difference between the centroid of the red color and the centroid of the blue color for image 3.jpg?
ii) Why are the centroids of the red and the blue color the same for images 4.jpg-6.jpg?
iii) Considering images 7.jpg-9.jpg, why is "red x" the greatest for the image 8.jpg and is the smallest for the image 9.jpg?

In [ ]:
#centroid
featuresNames_CentroidColors = ["red x", "red y",
                 "green x", "green y",
                 "blue x", "blue y"]

# TODO
#def featuresExtractor_CentroidColors(image):
#    values = []
#    return values
    
e2 = Exercise("exercise1/intro/", featuresNames_CentroidColors, featuresExtractor_CentroidColors)
e2.display(scale = 1.0)

2.2) Some properties of the image (object) which may be found via image moments are called invariants. Moment invariants are properties of the object which do not change with respect to some specific tranformations, e.g., a translation, a scale, or a rotation. Execute the below code. All of the displayed pictures contain the same object. Yet, the difference is that location, size, and orientation of this object is different from one picture to another.

In [ ]:
scale = 1.0
figure(figsize=(9.0 * scale, 4.0 * scale), dpi=80)
subplot(2, 2, 1); plt.imshow(io.imread("exercise2/base/hu1.jpg")) 
subplot(2, 2, 2); plt.imshow(io.imread("exercise2/base/hu2.jpg")) 
subplot(2, 2, 3); plt.imshow(io.imread("exercise2/base/hu3.jpg")) 
subplot(2, 2, 4); plt.imshow(io.imread("exercise2/base/hu4.jpg")) 
plt.show()

2.2) Hu moments is a vector of 7 values which are invariant (as a vector) with respect to translation, scale, and rotation. It means that Hu moments derived from the above images should be the same. In this Exercise you are asked to complete featuresExtractor_Hu method which has to return Hu moments for a given input image. As you may notice, this image is firstly converted to the grayscale and, later, the computed Hu moments are normalised (lambda function). To compute Hu Moments (hu = [ ]) you have to, step by step:
1) Compute raw moments (method moments())
2) Compute central moments (method moments_central())
3) Compute normalized moments (method moments_normalised())
4) Compute Hu moments (method moments_hu())
See the documentation of the scikit package (module measure) for a detailed information about how to use the above methods.

In [ ]:
norm = lambda x: -np.sign(x)*np.log10(np.abs(x))

featuresNames_Hu = ["hu1", "hu2", "hu3","hu4", "hu5", "hu6","hu7"]

# TODO
#def featuresExtractor_Hu(image):
#    img = rgb2gray(image)
#    hu = []
#    l = [norm(f) for f in hu]
#    return l
    
e2 = Exercise("exercise2/base/", featuresNames_Hu, featuresExtractor_Hu)

2.3) Search for the most similar images to q1.jpg. Verify the results (you can use the cosineSimilarity method). Why are some of the computed Hu moments different from one image to another (these images which contain the same object), while they should not?

In [ ]:
e2.searchForImage("exercise2/query/", "q1.jpg", cosineSimilarity)

2.4) Repeat the previous task for query = q2.jpg.

In [ ]:
e2.searchForImage("exercise2/query/", "q2.jpg", cosineSimilarity)

Exercise 3: Texture + Gabor's Filter

3.1) Apart from the color and the shape, a texture is an important characteristic of an object/image. Run the below code. In this Exercise you are asked to implement simple search engine based on Gabor's filter. Gabor's filter is a linear filter used for texture analysis. It can be applied to an image to detect specyfic frequency content (pattern). This involves different frequencies as well as the sizes of this content. Gabor's filter is a Gaussian kernel function modulated by a sinusoidal wave. Look at the below figures. They illustrate several Gabor's filters which are different with repect to the orientation (angle) and the frequency. You may change the values of angles and freqs arrays and run the script again to see the results. However, restore their original values for the remainder of this exercise.

In [ ]:
std = 10.0

#angles = [0, 30, 60, 90]
#freqs = [0.03, 0.05, 0.07, 0.09]
angles = [0, 30, 60, 90]
freqs = [0.03, 0.05, 0.07, 0.09]

scale = 1.0
kernels = []

for angle in angles:
    kernels_row = []
    figure(figsize=(14.0 * scale, 4.0 * scale), dpi=80)
    num = 0
    for freq in freqs:
        num += 1
        kernel = np.real(gabor_kernel(freq, theta=angle / 90.0 * 0.5 * np.pi, sigma_x=std, sigma_y=std))
        kernels_row.append(kernel)
        subplot(1, 4, num); plt.imshow(kernel, cmap='jet', vmin=-0.002, vmax=0.002) 
        plt.colorbar(orientation='horizontal', ticks = [-0.002, 0.0, 0.002])
    kernels.append(kernels_row)
plt.show()

3.2) The above filters (kernels) are convolved with the original picture. The obtained results of the convolution are images which represents frequency contant (size, orientation, frequency) which appears in the original image. Run the below script (ignore the last image):

i) The image b1.jpg illustrates a zebra. Do you see the pattern?
ii) The below pictures are the results of the convolution. Compare them with the previously (above) illustrated Gabor's filters (kernels). Why is the outcome of the convolution the most visible for the kernels with the lowest frequencies (0.03, 0.05) and for the kernels with the lowest angles (0.0, 30.0)?
iii) Change b1.jpg to b10.jpg. Why is the outcome equally visible for all of the considered angles?

There are many ways to incorporate Gabor's filters to image recognition. Usually, feature vectors are derived directly from the outomes of the convolution and the machine learning is involved to build a prediction model. In this exercise, you are asked to use a very simple apporach rather than the machine learning. Your task is to aggregate the outcomes of the convolution in order to generate a single image which represents frequency content detected in the original image. For that purpose, complete the three TODOs in the below code such that an averaged outcome of the img_convolve outcomes is generated. Run the script again and the the results (last image).

In [ ]:
image = rgb2gray(io.imread("exercise3/base/b1.jpg"))
io.imshow(image)

# TODO: init sum_image with zeros (np. zero). The matrix must be of a proper size (image.shape)
# sum_image = []

for row in kernels:
    figure(figsize=(14.0 * scale, 4.0 * scale), dpi=80)
    num = 0
    for kernel in row:
        num += 1
        img_convolve = fftconvolve(image, kernel, mode='same')  
    
        # TODO
        # add img_convovle to sum_image
        # sum_image = 
        
        subplot(1, 4, num); plt.imshow(img_convolve, cmap='jet', vmin=0.0, vmax=0.5) 
        plt.colorbar(orientation='horizontal', ticks=[0.0, 0.5])
        
# TODO compute the averaged values (divide sum_image by the number of kernels = 16)
averaged_image = [[1]]

plt.show()
figure(figsize=(4.0 * scale, 4.0 * scale), dpi=80)
subplot(1, 1, 1); plt.imshow(averaged_image, cmap='jet', vmin=0.0, vmax=0.5) 
plt.colorbar(orientation='horizontal', ticks=[0.0, 0.25, 0.5])
plt.show()

3.3) Complete the applyGaborsFilters method such that it returns an averaged image (outcomes of convolution; you can just copy the code you finished in the previous step).

In [ ]:
# TODO
#def applyGaborsFilters(image):
#    return []

3.4) Run the below script and analyse the results of applyGaborsFilters() method for different images. Consider the images with the stripes and these without the stripes (grain). These are the two textures which are considered in this exercise. What measure (mean, std, e.t.) may give different results for these two textures and may be used as a measure of similarity?

In [ ]:
def displayGabors():
    scale = 1.0
    collection1 = io.imread_collection("exercise3/base/*.jpg") 
    collection2 = io.imread_collection("exercise3/query/*.jpg")  
    images1 = [collection1[i] for i in range(0, len(collection1))]
    images2 = [collection2[i] for i in range(0, len(collection2))]
    images = images1 + images2
    for image in images:
        figure(figsize=(10.0 * scale, 5.0 * scale), dpi=80)
        gabor_image = applyGaborsFilters(image)
        subplot(1, 2, 1); plt.imshow(image) 
        subplot(1, 2, 2); plt.imshow(gabor_image, cmap='jet', vmin=0.0, vmax=0.5)
        plt.show()
displayGabors()

3.5) In this exercise you are asked to make a simple search engine for finding images based on the texture. For this purpose:

i) Complete the featuresExtractor_Texture method. Firstly, it should use applyGaborsFilters method to generate an anverge outcome of the convolution for 16 Gabor's filters which were previously generated. Then, the method should return a feature vector consisting of the mean, the standard deviation, the skeweness, and the kurtosis of values of the generated image. The kurtosis is a fourth color moment and it measures how flat (or tall) the distribution is in comparison to normal distribution.
ii) Complete the weightedSumSimilarity method. It should compute a weighted sum of the absolute values of the differences between the values of the subsequent characteristics (features). Remember that the smaller is that sum the greater is the similarity but the method expects that with the greater similarity the greater is the outcome.

Run the below four scripts and analyse the results. Do you find them satisfactory? Which feature accounts for measuring similarity the most? Try to manipulate the weights in order to improve the results.

In [ ]:
featuresNames_Texture = ["Mean", "Std", "Skew","Kurt"]

# TODO
#def featuresExtractor_Texture(image):
#   img = applyGaborsFilters(image)
#   return [1]

# TODO 
#def weightedSumSimilarity(featuresQuery, featuresImage):
#    w = [1.0, 1.0, 1.0, 1.0]
#    score = 0.0
#    return score

e3 = Exercise("exercise3/base/", featuresNames_Texture, featuresExtractor_Texture)
In [ ]:
e3.searchForImage("exercise3/query/", "q1.jpg", weightedSumSimilarity)
In [ ]:
e3.searchForImage("exercise3/query/", "q2.jpg", weightedSumSimilarity)
In [ ]:
e3.searchForImage("exercise3/query/", "q3.jpg", weightedSumSimilarity)
In [ ]:
e3.searchForImage("exercise3/query/", "q4.jpg", weightedSumSimilarity)
In [ ]: